
/*========================================================================================
 *                                                                                      *
 *               Copyright(c) 2013-2014, Cha SangWoo, All rights reserved.              *
 *                                                                                      *
 * This file is part of ChaOS.                                                          *
 *                                                                                      *
 * Permission to use, copy, modify, and distribute this software in source and binary   *
 * forms and its documentation for any purpose and without fee is hereby granted,       *
 * provided that the above copyright notice appear in all copies and that both that     *
 * copyright notice and this permission notice appear in supporting documentation.      *
 *                                                                                      *
 * THIS SOFTWARE IS PROVIDED BY THE CHA SANGWOO AND CONTRIBUTORS "AS IS" AND ANY        *
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED            *
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.   *
 * IN NO EVENT SHALL CHA SANGWOO OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,    *
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT         *
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,          *
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF            *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE      *
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,                    *
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                   *
 *                                                                                      *
========================================================================================*/

#include "co_core.h"
#include "co_sw_timer.h"

#if (FLAG_USE_CHAOS_SW_TIMER == CO_ENABLE)

#ifdef __cplusplus
    namespace ChaOS {
#endif

//////////////////////////////////////  < BEGIN >  ///////////////////////////////////////

/*======================================================================================*/
/*
    @fn             OBJECT co_timer_create(VOID)

    @brief          

    @param [in]     object - The size of new thread's stack
    @param [in]     pname - The priority of new thread
    @param [in]     pname - argument for new thread

    @return         Object for timer.
*/
/*======================================================================================*/
OBJECT co_timer_create(VOID)
{
    TIMER_CB   *ptimer;

    // allocate heap memory
    ptimer = (TIMER_CB*) co_heap_alloc(sizeof(TIMER_CB));
    CO_ASSERT(ptimer);

    // set object ID
    OBJID_SET(ptimer, OBJ_TIMER_ID);

    ptimer->state = CO_TIMER_STOP;

    // add timer list
    ptimer->pnext = _gp_timer_list;
    _gp_timer_list = ptimer;

    return (OBJECT) ptimer;
}


/*======================================================================================*/
/*
    @fn             VOID co_timer_set_procedure(OBJECT object, TIMER_PROC porc)

    @brief          

    @param [in]     object - The size of new thread's stack
    @param [in]     pname - The priority of new thread
    @param [in]     pname - argument for new thread

    @return         Object for timer.
*/
/*======================================================================================*/
VOID co_timer_set_procedure(OBJECT object, TIMER_PROC proc, VOID *parg)
{
    TIMER_CB   *ptimer = (TIMER_CB*) object;

    // check object ID
    OBJID_CHECK(ptimer, OBJ_TIMER_ID);

    ///////////////////
    CO_ENTER_CRITICAL();

    ptimer->state = CO_TIMER_STOP;
    ptimer->proc  = proc;
    ptimer->parg  = parg;

    CO_LEAVE_CRITICAL();
    ////////////////////
}


/*======================================================================================*/
/*
    @fn             VOID co_timer_start(OBJECT  object, 
                                        UINT    id, 
                                        UINT16  timeout, 
                                        BOOL    repeate)

    @brief          

    @param [in]     object - 
    @param [in]     id
    @param [in]     timeout
    @param [in]     repeate

    @return         Object for timer.
*/
/*======================================================================================*/
VOID co_timer_start(OBJECT  object, 
                    UINT16  id, 
                    UINT16  timeout,
                    BOOL    repeate)
{
    TIMER_CB   *ptimer = (TIMER_CB*) object;

    // check object ID
    OBJID_CHECK(ptimer, OBJ_TIMER_ID);

    ///////////////////
    CO_ENTER_CRITICAL();

    ptimer->state = CO_TIMER_START;
    ptimer->id = id;
    ptimer->wait_time = (UINT16) PORT_GET_TICK_IN_MS(timeout);

    if (repeate == TRUE)
    {
        ptimer->state |= CO_TIMER_REPEATE;
        ptimer->repeat_time = ptimer->wait_time;
    }

    CO_LEAVE_CRITICAL();
    ////////////////////
}


/*======================================================================================*/
/*
    @fn             VOID co_timer_stop(OBJECT object)

    @brief          

    @param [in]     object - 

    @return         Object for timer.
*/
/*======================================================================================*/
VOID co_timer_stop(OBJECT object)
{
    TIMER_CB   *ptimer = (TIMER_CB*) object;

    // check object ID
    OBJID_CHECK(ptimer, OBJ_TIMER_ID);

    ///////////////////
    CO_ENTER_CRITICAL();

    ptimer->state = CO_TIMER_STOP;

    CO_LEAVE_CRITICAL();
    ////////////////////
}

//////////////////////////////////////  <  END  >  ///////////////////////////////////////

#ifdef __cplusplus
    } /* namespace ChaOS */
#endif

#endif // (FLAG_USE_CHAOS_SW_TIMER == CO_ENABLE)

